import { system } from "@minecraft/server";
import { SimulatedPlayer } from "@minecraft/server-gametest";
import { ActionFormData, ActionFormResponse, ModalFormData, ModalFormResponse } from "@minecraft/server-ui";
import { CommonForm, formManager, SAPIProForm } from "sapi-pro";
import { isAdmin, isNum, tointloc } from "sapi-pro/scripts/func";
import { dimName } from "../static";
import { spNameValidator } from "./spCommands";
import { SPAction, spConfig, spData, spManager } from "./SPManager";

const spConfigForm: SAPIProForm<ModalFormData> = {
    builder: (player, args) => {
        const config = spManager.Config ?? {
            structurePos: undefined,
            spPrefix: "[假人]",
        };
        const form = new ModalFormData()
            .title("设置假人结构")
            .textField("输入假人结构坐标", "请输入假人结构坐标(例如114514,230,114514)", {
                defaultValue: Object.values(config.structurePos ?? {}).join(",") ?? "",
                tooltip: "假人需要生成结构，请生成在较远处，防止玩家遇到",
            })
            .textField("假人前缀", "推荐设为中文或特殊字符(1-10个字符)", {
                defaultValue: config.spPrefix,
                tooltip: "假人名字为:[前缀]xxx",
            });
        return form;
    },
    handler: (res: ModalFormResponse, ctx) => {
        const player = ctx.player;
        if (!res.formValues) return;
        const posText = ((res.formValues[0] as string) ?? "").split(",");
        const prefix = (res.formValues[1] as string) ?? "";
        if (!posText.every((t) => isNum(t))) {
            return spManager.mes(player, "请输入正确的结构坐标");
        }
        if (prefix.length == 0 || prefix.length > 10) {
            return spManager.mes(player, "请输入适当的假人前缀");
        }
        const pos = posText.map((t) => parseInt(t));
        if (pos[1] > 320 || pos[1] < -60) return spManager.mes(player, "请输入合理的y坐标");
        const config: spConfig = {
            structurePos: { x: pos[0], y: pos[1], z: pos[2] },
            spPrefix: prefix,
        };
        if (spManager.setConfig(config)) {
            spManager.mes(player, "假人结构配置成功");
        } else {
            spManager.mes(player, "假人结构配置失败");
        }
        return;
    },
};
const spInit = CommonForm.ButtonForm({
    title: "假人管理",
    body: "假人未初始化，请点击初始化",
    buttonGenerator: (player, args) => {
        if (isAdmin(player)) {
            return {
                假人结构配置: {
                    func: (ctx) => {
                        return ctx.push(spConfigForm);
                    },
                },
            };
        }
    },
    buttons: {
        初始化: {
            func: async (ctx) => {
                spManager.mes(ctx.player, "请等待初始化...");
                const ans = await spManager.initStructure();
                if (ans) return ctx.offAllNamed("sp.main");
                spManager.mes(ctx.player, "假人初始化失败!");
                return;
            },
        },
    },
});

const spMainForm = CommonForm.ButtonForm({
    title: "假人管理",
    body: "请选择选项",
    buttonGenerator: (player, args) => {
        if (isAdmin(player)) {
            return {
                假人结构配置: {
                    func: (ctx) => {
                        return ctx.push(spConfigForm);
                    },
                },
            };
        }
    },
    buttons: {
        创建假人: {
            func: (ctx) => {
                return ctx.push(spCreate);
            },
        },
        假人列表: {
            func: (ctx) => {
                return ctx.push(spList);
            },
        },
    },
    validator: (ctx) => {
        const ans = spManager.isLoaded();
        if (ans) return;
        if (spManager.getConfig() == undefined && isAdmin(ctx.player)) {
            return ctx.offAll(spConfigForm, {}, 10);
        }
        ctx.offAll(spInit);
    },
});

formManager.registerNamed("sp.main", spMainForm);

const spList = CommonForm.ButtonListForm({
    title: "假人列表",
    generator: (form, player, args) => {
        const spList = spManager.getSPList();
        form.button("返回");
        for (let spdata of spList) {
            form.button(spdata.sp.name);
        }
        args.list = spList;
    },
    handler: (selection, ctx) => {
        if (selection == 0) return ctx.back();
        ctx.push(spInfo, { spdata: ctx.args.list[selection - 1] });
    },
    validator: (ctx) => {
        if (spManager.getSPList().length == 0) {
            spManager.mes(ctx.player, "没有假人，请先创建");
            ctx.back();
        }
    },
});

const spItemsForm = CommonForm.ButtonListForm({
    title: "假人物品",
    generator(form, player, args) {
        const items = args.items as { name: string; slot: number }[];
        for (let item of items) {
            form.button({ translate: item.name });
        }
    },
    handler(selection, ctx) {
        const items = ctx.args.items as { name: string; slot: number }[];
        spManager.useItemOnBlock(ctx.args.sp, items[selection].slot);
    },
});

const spInfo: SAPIProForm<ActionFormData> = {
    builder: async (player, args) => {
        const form = new ActionFormData().title("假人详情");
        const spdata = args.spdata as spData;
        const sp = spdata.sp;
        const item = spManager.getHandItem(sp);

        form.body({
            rawtext: [
                {
                    text: `假人名:§e${sp.name}§r\n假人坐标:${dimName[sp.dimension.id]}§r(${tointloc(sp.location).join(
                        ","
                    )})\n`,
                },
                { text: "假人手持:" },
                item == undefined ? { text: "无" } : { translate: item.localizationKey },
            ],
        });
        form.button("返回")
            .button("原地跳" + (spdata.acts?.jump != undefined ? "§q[开]" : "§m[关]"))
            .button("自动跟随" + (spdata.acts?.follow != undefined ? "§q[开]" : "§m[关]"))
            .button("自动挖掘" + (spdata.acts?.break != undefined ? "§q[开]" : "§m[关]"))
            .button("修改视角")
            .button("使用物品")
            .button("杀死假人");
        return form;
    },
    handler: (res: ActionFormResponse, ctx) => {
        if (res.selection == undefined) return undefined;
        const sp = ctx.args.spdata.sp as SimulatedPlayer;
        switch (res.selection) {
            case 0:
                return ctx.back();
            case 1:
                SPAction.call(sp.name, "jump");
                return ctx.reopen();
            case 2:
                SPAction.call(sp.name, "follow", ctx.player);
                return ctx.reopen();
            case 3:
                SPAction.call(sp.name, "break");
                return ctx.reopen();
            case 4:
                spManager.setLookAt(ctx.player, sp);
                break;
            case 5:
                const items = spManager.getInv(sp);
                if (items == undefined) {
                    ctx.player.sendMessage("无法获取假人物品栏");
                    return ctx.reopen();
                }
                ctx.push(spItemsForm, { items: items, sp: sp });
                break;
            case 6:
                spManager.Remove(sp);
                return ctx.back();
        }
    },
};

const spCreate: SAPIProForm<ModalFormData> = {
    builder: async (player, context) => {
        const form = new ModalFormData().title("创建假人").textField("假人名字", "输入假人名字，不能有特殊字符");
        return form;
    },
    handler: (res: ModalFormResponse, ctx) => {
        const player = ctx.player;
        if (res.formValues == undefined) return;
        const name = res.formValues[0] as string;
        const validation = spNameValidator(name, player);
        if (validation == true) {
            system.run(() => {
                const sp = spManager.Spawn(name, player.location, {
                    dimension: player.dimension,
                    rotation: player.getRotation(),
                });
                if (sp instanceof SimulatedPlayer) {
                    spManager.setLookAt(ctx.player, sp);
                } else {
                    spManager.mes(player, sp);
                }
            });
        } else {
            spManager.mes(player, validation);
            return ctx.reopen();
        }
    },
};
